package compteurlignecode;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.UIManager;


public class NewJFrame extends javax.swing.JFrame {

	String DEFAULT_REP = "I:\\Mes Docs\\Perso\\progr_sauvegarde_DellHome" ;
	private File repBase;

	private int nbFile = 0;
	private int nbTotalLineCode = 0;
	private int nbTotalLineComment = 0;


    public NewJFrame() {
        initComponents();

		repBase = new File (DEFAULT_REP);
    }

    public static void main(String args[]) {
		try {
			//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch (Exception ex) {}


        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jLabel1 = new javax.swing.JLabel();
        tf_NbFile = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        tf_TotalRealCode = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        tf_TotalAvecComment = new javax.swing.JTextField();
        tf_CurrentSource = new javax.swing.JTextField();
        btn_GoForCurrentSource = new javax.swing.JButton();
        tf_CurrentSource_passerelle = new javax.swing.JTextField();
        btn_GoForCurrentSource_passerelle = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("Choix rep");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jList1ValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jList1);

        jLabel1.setText("Nb fichiers :");

        jLabel2.setText("Total real code :");

        jLabel3.setText("Total avec comment :");

        tf_CurrentSource.setText("C:\\$DOCS\\$Docs_Olivier\\docs\\$Programation\\Java\\Generalisation\\projets\\ProjetG_v04\\src");

        btn_GoForCurrentSource.setText("current source");
        btn_GoForCurrentSource.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_GoForCurrentSourceActionPerformed(evt);
            }
        });

        tf_CurrentSource_passerelle.setText("C:\\$DOCS\\$Docs_Olivier\\docs\\$Programation\\Java\\Generalisation\\PasserelleESRI\\ProjetVCS\\AutoGENE_PasserelleESRI");

        btn_GoForCurrentSource_passerelle.setText("current source");
        btn_GoForCurrentSource_passerelle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_GoForCurrentSource_passerelleActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(tf_CurrentSource, javax.swing.GroupLayout.DEFAULT_SIZE, 644, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(46, 46, 46)
                                .addComponent(jLabel1)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(tf_NbFile, javax.swing.GroupLayout.DEFAULT_SIZE, 89, Short.MAX_VALUE)
                            .addComponent(tf_TotalRealCode)
                            .addComponent(tf_TotalAvecComment))
                        .addGap(131, 131, 131))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btn_GoForCurrentSource)
                        .addContainerGap(549, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addContainerGap(573, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(tf_CurrentSource_passerelle, javax.swing.GroupLayout.DEFAULT_SIZE, 644, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btn_GoForCurrentSource_passerelle)
                        .addContainerGap(549, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tf_CurrentSource, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(6, 6, 6)
                .addComponent(btn_GoForCurrentSource)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(tf_CurrentSource_passerelle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btn_GoForCurrentSource_passerelle)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(45, 45, 45)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(tf_NbFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel1))
                        .addGap(12, 12, 12)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(tf_TotalRealCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tf_TotalAvecComment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3))
                        .addGap(227, 227, 227)
                        .addComponent(jButton1)
                        .addContainerGap(58, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 317, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(87, 87, 87))))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
		// Choix du répertoire
		JFileChooser fc = new JFileChooser(repBase);
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fc.showDialog(this, "répertoire de base");
		repBase = fc.getSelectedFile();

		if (repBase == null) {
			repBase = new File (DEFAULT_REP);
			return;
		}
		
		//remplissage de la liste des fichiers de ce répertoire
		DefaultListModel lm = new DefaultListModel();
		File[] tabFile = repBase.listFiles();

		for (File f : tabFile)
			lm.addElement(f.getName());

		jList1.setModel(lm);

	}//GEN-LAST:event_jButton1ActionPerformed

	private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jList1ValueChanged
		if (evt.getValueIsAdjusting()) return;

		String fileName = (String) jList1.getSelectedValue();
		traiteZipFile(fileName);
		showStats();
	}//GEN-LAST:event_jList1ValueChanged

	private void btn_GoForCurrentSourceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btn_GoForCurrentSourceActionPerformed
		traiteRep(tf_CurrentSource.getText());
		showStats();
	}//GEN-LAST:event_btn_GoForCurrentSourceActionPerformed

	private void btn_GoForCurrentSource_passerelleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btn_GoForCurrentSource_passerelleActionPerformed
		traiteRep(tf_CurrentSource_passerelle.getText());
		showStats();
	}//GEN-LAST:event_btn_GoForCurrentSource_passerelleActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btn_GoForCurrentSource;
    private javax.swing.JButton btn_GoForCurrentSource_passerelle;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JList jList1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField tf_CurrentSource;
    private javax.swing.JTextField tf_CurrentSource_passerelle;
    private javax.swing.JTextField tf_NbFile;
    private javax.swing.JTextField tf_TotalAvecComment;
    private javax.swing.JTextField tf_TotalRealCode;
    // End of variables declaration//GEN-END:variables



	private void initStat() {
		nbFile = 0;
		nbTotalLineCode = 0;
		nbTotalLineComment = 0;
		tf_NbFile.setText("");
		tf_TotalRealCode.setText("");
		tf_TotalAvecComment.setText("");
	}

	private void showStats() {
		tf_NbFile.setText(""+nbFile);
		tf_TotalRealCode.setText(""+nbTotalLineCode);
		tf_TotalAvecComment.setText(""+(nbTotalLineCode+nbTotalLineComment));
	}


	private void traiteZipFile(String fileName) {
		initStat();
		if (!fileName.toLowerCase().endsWith(".zip")) return;

		tf_NbFile.setText("");
		tf_TotalRealCode.setText("");
		tf_TotalAvecComment.setText("");

		try {
			ZipFile zipFile = new ZipFile(repBase.getPath() + "\\" + fileName);
			Enumeration zipEntries = zipFile.entries();

			while (zipEntries.hasMoreElements()) {
				ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
				//System.out.println(zipEntry.getName());
				if (!zipEntry.getName().toLowerCase().endsWith(".java")) continue;

				nbFile++;

				// Ouverture du fichier java
				System.out.println("Lecture du fichier : " + zipEntry.getName());
				InputStream is = zipFile.getInputStream(zipEntry);
				Vector<String> vLines = readStream(is);

				traiteVLineCode(vLines);
			}

			zipFile.close();
			
		} catch (IOException ex) {
			Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
		}
	}


	private void traiteRep(String repName) {
		initStat();
		traiteRep_rec(repName);
	}

	private void traiteRep_rec(String repName) {

		File rep = new File (repName);
		if (!rep.exists() || !rep.isDirectory()) return;

		try {

			File[] filesInRep = rep.listFiles();

			for (File f : filesInRep) {
				if (f.getPath().toLowerCase().endsWith(".java") || f.getPath().toLowerCase().endsWith(".cs")) {
					nbFile++;

					// Ouverture du fichier java
					System.out.println("Lecture du fichier : " + f.getName());
					InputStream is = new FileInputStream(f);
					Vector<String> vLines = readStream(is);
					traiteVLineCode(vLines);
					
				} else if (f.isDirectory()) {
					//appel recursif
					traiteRep_rec(f.getPath());
				}
			}

		} catch (IOException ex) {
			Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
		}
	}



	private void traiteVLineCode (Vector<String> vLines) {
		System.out.println(" - nb ligne total (vide compris) : " + vLines.size());

		int nbLineCode = 0;
		int nbLineComment = 0;

		for(String line : vLines) {
			String lineTrimmed = line.trim();
			if (lineTrimmed.length()>0) {
				if (lineTrimmed.startsWith("//") || lineTrimmed.startsWith("/*") ||
					lineTrimmed.startsWith("*")  || lineTrimmed.endsWith("*/")) {
					// c'est un commentaire
					nbLineComment++;
				} else {
					nbLineCode++;
				}
			}
		}
		System.out.println(" - nb ligne code                 : " + nbLineCode);
		System.out.println(" - nb ligne commentaires         : " + nbLineComment);

		nbTotalLineCode += nbLineCode;
		nbTotalLineComment += nbLineComment;
	}
	

	Vector<String> readStream (InputStream is) {
		try {
			InputStreamReader isr = new InputStreamReader(is, "ISO-8859-1");
			BufferedReader br = new BufferedReader(isr);
			String ligne;
			Vector<String> vLigne = new Vector<String>(30000);
			while ((ligne = br.readLine()) != null)
				vLigne.add (ligne.replace(',', '.'));

			br.close();
			return vLigne;

		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
			return null;
		} catch (IOException ex) {
			ex.printStackTrace();
			return null;
		}
	}
}
